package com.songyang.client;

import com.songyang.client.handler.ClientHandler;
import com.songyang.common.ExceptionHandler;
import com.songyang.common.YoungSQLException;
import com.songyang.serialize.SerializeFactory;
import com.songyang.serialize.inter.YoungSqlSerialize;
import com.songyang.transport.YoungSQLDataPackage;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.ConnectException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * @ClassName YoungSqlClient
 * @Description
 * @date 2022/12/23 16:37
 * @Author yanceysong
 * @Version 1.0
 */
public class YoungSqlClient {
    private static Integer YOUNG_SQL_SERVER_PORT = 12009;
    private static final String IP="127.0.0.1";

    public YoungSqlClient() {
        //没有配置文件
        YOUNG_SQL_SERVER_PORT = 12009;
    }

    public static void main(String[] args)  {
        //客户端需要一个事件循环组
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        //创建一个客户端启动对象
        //注 客户端用Bootstrap而不是ServerBootstrap
        Bootstrap bootstrap = new Bootstrap();
        //设置相关参数
        bootstrap.group(eventLoopGroup)
                //设置线程组
                .channel(NioSocketChannel.class)
                //设置客户端通道的实现类
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new ClientHandler());//加入自己的处理器
                    }
                });
        ChannelFuture channelFuture = null;
        //启动客户端去连接服务器端
        try {
            //netty的异步模型
            channelFuture = bootstrap.connect(IP, YOUNG_SQL_SERVER_PORT).sync();
            //给关闭通道进行监听
            Channel channel = channelFuture.channel();
            Scanner sc = new Scanner(System.in);
            StringBuilder sb = null;
            while (true) {
                String s = sc.nextLine().trim();
                //退出指令
                if (sb == null && ("exit".equals(s) || "quit".equals(s))) {
                    sc.close();
                    break;
                }
                //空字符串
                if ("".equals(s)) {
                    System.out.print("> > ");
                    continue;
                }
                if (sb == null) {
                    sb = new StringBuilder();
                }
                sb.append(s).append(" ");
                //如果sql以分号结尾，并且不以分号开头则将该SQL传给server
                if (sb.length() > 1 && s.endsWith(";")) {
                    channel.writeAndFlush(Unpooled.copiedBuffer(
                            SerializeFactory.getDecoder()
                                    .serialize(new YoungSQLDataPackage(sb.toString().replaceAll("\\s+"," "), null))));
                   //传输之后，sb重新为空
                    sb = null;
                }else {
                    System.out.print("> > ");
                }
            }
        } catch (InterruptedException | YoungSQLException e) {
            ExceptionHandler.handler(e);
        } catch (Exception e){
            System.out.println(e.getMessage());
        }finally {
            eventLoopGroup.shutdownGracefully();
        }
        System.out.println("bye！");
    }
}
